package net.logax.games.chase.map;

import java.util.ArrayList;

import net.logax.games.chase.map.Map.MapFragment;

public class CandidateFinderByPreviousNY implements CandidateFinder {

	private Map.MapFragment fragX;
	private Map.MapFragment fragNX;
	private Map.MapFragment fragNY;
	private Map.MapFragment fragY;
	private Map.MapFragment fragNXY;
	private Map.MapFragment fragXY;
	private Map.MapFragment fragNXNY;
	private Map.MapFragment fragXNY;

	private int creationIndexX;
	private int creationIndexY;
	private int creationIndexZ;

	public CandidateFinderByPreviousNY(Map.MapFragment[][][] mapArray, int[] currentCoordinate) {
		creationIndexX = currentCoordinate[0];
		creationIndexY = currentCoordinate[1];
		creationIndexZ = currentCoordinate[2];
		fragNX = mapArray[creationIndexX - 1][creationIndexY][creationIndexZ];
		fragX = mapArray[creationIndexX + 1][creationIndexY][creationIndexZ];
		fragNY = mapArray[creationIndexX][creationIndexY - 1][creationIndexZ];
		fragY = mapArray[creationIndexX][creationIndexY + 1][creationIndexZ];
		fragNXY = mapArray[creationIndexX - 1][creationIndexY + 1][creationIndexZ];
		fragXY = mapArray[creationIndexX + 1][creationIndexY + 1][creationIndexZ];
		fragNXNY = mapArray[creationIndexX - 1][creationIndexY - 1][creationIndexZ];
		fragXNY = mapArray[creationIndexX + 1][creationIndexY - 1][creationIndexZ];
	}

	/**
	 * Erstellungsmarker war zuvor bei NY
	 */
	public ArrayList<Map.MapFragment> findCandidates(int corridorLength, int corridorSegmentCount) throws Exception {
		ArrayList<Map.MapFragment> possibilities = new ArrayList<Map.MapFragment>();
		if (MapBuilder.DEBUG) {
			MapDebugUtils.printSurrounding(this, fragNX, fragX, fragNY, fragY, fragNXY, fragXY, fragNXNY, fragXNY);
		}

		if (fragNY.equals(Map.MapFragment.CORRIDOR_Y)) {
			checkDirectionY(corridorLength, corridorSegmentCount, possibilities);
			checkDirectionX(corridorLength, corridorSegmentCount, possibilities);
			checkDirectionNX(corridorLength, corridorSegmentCount, possibilities);
			checkDirectionsXNX(corridorLength, corridorSegmentCount, possibilities);
		} else if (fragNY.equals(Map.MapFragment.CURVE_X_Y) || (fragNY.equals(Map.MapFragment.T_CROSSING_X))) { // TODO
			checkDirectionY(corridorLength, corridorSegmentCount, possibilities);
			checkDirectionX(corridorLength, corridorSegmentCount, possibilities);
		} else if (fragNY.equals(Map.MapFragment.CURVE_NX_Y) || (fragNY.equals(Map.MapFragment.T_CROSSING_NX))) {// TODO
			checkDirectionY(corridorLength, corridorSegmentCount, possibilities);
			checkDirectionNX(corridorLength, corridorSegmentCount, possibilities);
		} else if (fragNY.equals(Map.MapFragment.CROSSING) || (fragNY.equals(Map.MapFragment.T_CROSSING_Y))) {// TODO
			checkDirectionY(corridorLength, corridorSegmentCount, possibilities);
		} else {
			throw new Exception("previous was NY, could not find a candidate");
		}
		if (MapBuilder.DEBUG) {
			System.out.println("Possibilities" + possibilities.toString());
		}
		return possibilities;
	}

	public int[] getPreviousCoordinates() {
		int[] previousCoordinates = { creationIndexX, (creationIndexY - 1), creationIndexZ };
		return previousCoordinates;
	}

	private void checkDirectionY(int corridorLength, int corridorSegmentCount, ArrayList<Map.MapFragment> possibilities) {
		if (fragY.equals(MapFragment.EMPTY)) {
			if (corridorSegmentCount < corridorLength) {
				if (MapBuilder.DEBUG) {
					System.out.println("checkDirectionY");
				}
				if ((fragX.equals(MapFragment.EMPTY) || fragX.equals(MapFragment.DEAD_END_X))
						&& (fragNX.equals(MapFragment.EMPTY) || fragNX.equals(MapFragment.DEAD_END_NX))) {
					possibilities.add(MapFragment.CORRIDOR_Y);
				}
			}
		}
	}

	private void checkDirectionsXNX(int corridorLength, int corridorSegmentCount, ArrayList<Map.MapFragment> possibilities) {
		if (MapBuilder.DEBUG) {
			System.out.println("checkDirectionXNX");
		}
		if (fragY.equals(MapFragment.EMPTY)) {
			if (corridorSegmentCount >= corridorLength) {

				if (fragX.equals(MapFragment.EMPTY) && fragNX.equals(MapFragment.EMPTY)) {
					if (fragNXNY.equals(MapFragment.EMPTY) && fragXNY.equals(MapFragment.EMPTY)) {
						if (fragXY.equals(MapFragment.EMPTY) && fragNXY.equals(MapFragment.EMPTY)) {
							possibilities.add(MapFragment.CROSSING);
						} else if ((fragXY.equals(MapFragment.EMPTY) || fragXY.equals(MapFragment.DEAD_END_Y))
								&& (fragNXY.equals(MapFragment.EMPTY) || fragNXY.equals(MapFragment.DEAD_END_Y))) {
							possibilities.add(MapFragment.T_CROSSING_NX);
						}
					}
				}
			}
		}
	}

	private void checkDirectionNX(int corridorLength, int corridorSegmentCount, ArrayList<Map.MapFragment> possibilities) {
		if (MapBuilder.DEBUG) {
			System.out.println("checkDirectionNX");
		}
		if (fragY.equals(MapFragment.EMPTY)) {
			if (fragNX.equals(MapFragment.EMPTY)) {
				if (fragNXNY.equals(MapFragment.EMPTY)) {
					if (fragNXY.equals(MapFragment.EMPTY)) {
						if (corridorSegmentCount >= corridorLength) {
							possibilities.add(MapFragment.T_CROSSING_NX);
						} else {
							possibilities.add(MapFragment.CURVE_NX_NY);
						}
					} else if (fragNXY.equals(MapFragment.DEAD_END_Y)) {
						possibilities.add(MapFragment.CURVE_NX_NY);
					}
				}
			}
		}
	}

	private void checkDirectionX(int corridorLength, int corridorSegmentCount, ArrayList<Map.MapFragment> possibilities) {
		if (MapBuilder.DEBUG) {
			System.out.println("checkDirectionX");
		}
		if (fragY.equals(MapFragment.EMPTY)) {
			if (fragX.equals(MapFragment.EMPTY)) {
				if (fragXNY.equals(MapFragment.EMPTY)) {
					if (fragXY.equals(MapFragment.EMPTY)) {
						if (corridorSegmentCount >= corridorLength) {
							possibilities.add(MapFragment.T_CROSSING_X);
						} else {
							possibilities.add(MapFragment.CURVE_X_NY);
						}
					} else if (fragXY.equals(MapFragment.DEAD_END_Y)) {
						possibilities.add(MapFragment.CURVE_X_NY);
					}
				}
			}
		}
	}
}
